package com.tubruk.object;

import java.io.IOException;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.List;

import android.location.Address;
import android.location.Geocoder;
import android.util.Log;

import com.tubruk.trackme.MyGeoPoint;

public class TrackSummary implements Serializable {
	private static final int DATATYPE_RECORD = 0;
	private static final int DATATYPE_IMPORT = 1;
	
	private long id;
	private List<MyGeoPoint> myGeoPoints;
	private double distance = 0.0;
	private float avgSpeed = 0;
	private float minSpeed = 0;
	private float maxSpeed = 0;
	private long timeStart = 0;
	private long timeStop = 0;
	private long timeSpent = 0;
	
	private int datatype = TrackSummary.DATATYPE_RECORD;
	private int mode;
	
	private String title = "";
	
	private Geocoder geoCoder;
	
	static DecimalFormat decimalFormat = new DecimalFormat("0.00");

	
	public void setDistance(double distance) {
		this.distance = distance;
	}

	public void setAvgSpeed(float avgSpeed) {
		this.avgSpeed = avgSpeed;
	}

	public void setMinSpeed(float minSpeed) {
		this.minSpeed = minSpeed;
	}

	public void setMaxSpeed(float maxSpeed) {
		this.maxSpeed = maxSpeed;
	}

	public void setTimeStart(long timeStart) {
		this.timeStart = timeStart;
	}

	public void setTimeStop(long timeStop) {
		this.timeStop = timeStop;
	}

	public void setTimeSpent(long timeSpent) {
		this.timeSpent = timeSpent;
	}

	public void setDatatype(int datatype) {
		this.datatype = datatype;
	}

	//geoCoder is optional
	public TrackSummary(List<MyGeoPoint> myGeoPoints, Geocoder geoCoder) {
		this.myGeoPoints = myGeoPoints;
		this.geoCoder = geoCoder;
	}
	
	//dipake utk history, history pas awal retrieve kaga nge-retrieve geopoints nya dulu
	public TrackSummary(){}
	
	public void setId(long id){
		this.id = id;
	}
	
	public long getId(){
		return this.id;
	}
	
	public void setMode(int mode){
		this.mode = mode;
	}
	
	public int getMode(){
		return this.mode;
	}
		
	public void setTitle(String title){
		this.title = title;
	}
	
	public String getTitle(){
		return this.title;
	}
	
	public int getDataType(){
		return this.datatype;
	}
	
	public List<MyGeoPoint> getGeoPoints(){
		return myGeoPoints;
	}
	
	public void setGeoPoints(List<MyGeoPoint> geoPoints){
		this.myGeoPoints = geoPoints;
	}
	
	public void refresh(){
		this.title = "";
		this.distance = 0.0;
		this.avgSpeed = 0;
		this.minSpeed = 0;
		this.maxSpeed = 0;
		this.timeStart = 0;
		this.timeStop = 0;
		this.timeSpent = 0;
		
	}

	public void summarize() {
		if (myGeoPoints != null) {
			int size = myGeoPoints.size();
			if (size > 0) {
				int i = 0;
				for (MyGeoPoint myg : myGeoPoints) {
					// summarize
					if (i == 0) {
						timeStart = myg.getTimeStart();
						
						if (title.equals("") && geoCoder != null){
							try {
								List<Address> addresses = geoCoder.getFromLocation(
										myg.getLongitudeE6() / 1E6, myg.getLongitudeE6() / 1E6, 1);
								
								if (addresses.size() > 0) {
									int size2 = addresses.get(0).getMaxAddressLineIndex();
									if (size2 > 0) {
										title += addresses.get(0).getAddressLine(0);
										for (int j = 1; i < size2; i++) {
											title += ", " + addresses.get(0).getAddressLine(j);
										}
									}
								}

							} catch (IOException e) {
								e.printStackTrace();
							}

						}
						
					} else {
						if (i == (size - 1)) {
							timeStop = myg.getTimeStart();
						}

						// count distance
						distance += myg.getDistance(myGeoPoints.get(i-1).getLocation());
					}

					if (minSpeed == 0 || minSpeed > myg.getSpeed()) {
						minSpeed = myg.getSpeed();
					}

					if (maxSpeed == 0 || maxSpeed < myg.getSpeed()) {
						maxSpeed = myg.getSpeed();
					}
					i++;
				}
			}

			avgSpeed = (minSpeed + maxSpeed) / 2;
			timeSpent = timeStop - timeStart;

			Log.d("SUMMARY avgSpeed: ", avgSpeed + "");
			Log.d("SUMMARY timeSpent: ", timeSpent + "");
			Log.d("SUMMARY timeSpent: ", getTimeSpentStr() + "");
			Log.d("SUMMARY distance: ", distance + "");
			Log.d("SUMMARY distance: ", getDistanceStr());
			Log.d("SUMMARY minSpeed: ", minSpeed + "");
			Log.d("SUMMARY maxSpeed: ", maxSpeed + "");
		}
		
		
	}
	
	public double getDistance() {
		return distance;
	}
	
	public String getDistanceStr() {
		if (distance != 0) {
			String s = "";
			if (distance > 1000) {
				s += NumberFormat.getIntegerInstance().format(Math.floor(distance/1000)) + " KM, " 
				+ decimalFormat.format(distance%1000) + " M";
			} else {
				s += decimalFormat.format(distance) + " meters";
			}
			return s;
		}
		return "N/A";
	}

	public float getAvgSpeed() {
		return avgSpeed;
	}
	
	public String getAvgSpeedStr() {
		if (avgSpeed != 0) {
			return decimalFormat.format(this.avgSpeed * 3.6) + " KM/H";
		}
		
		return "N/A";
	}

	public float getMinSpeed() {
		return minSpeed;
	}
	
	public String getMinSpeedStr() {
		if (minSpeed != 0) {
			return decimalFormat.format(this.minSpeed * 3.6) + " KM/H";
		}
		
		return "N/A";
	}

	public float getMaxSpeed() {
		return maxSpeed;
	}
	
	public String getMaxSpeedStr() {
		if (maxSpeed != 0) {
			return decimalFormat.format(this.maxSpeed * 3.6) + " KM/H";
		}
		
		return "N/A";
	}

	public long getTimeStart() {
		return timeStart;
	}
	
	public String getTimeStartStr() {
		if (timeStart != 0) {
			return DateFormat.getTimeInstance().format(new Date(timeStart));
		}
		return "N/A";
	}
	
	public String getDateStartStr() {
		if (timeStart != 0) {
			return DateFormat.getDateInstance().format(new Date(timeStart));
		}
		return "N/A";
	}

	public long getTimeStop() {
		return timeStop;
	}

	public long getTimeSpent() {
		return timeSpent;
	}
	
	public String getTimeSpentStr() {
		if (timeSpent != 0) {
			String time = "";
			String format = String.format("%%0%dd", 2);  
		    long elapsedTime = timeSpent / 1000;
		    String seconds = String.format(format, elapsedTime % 60);
		    String minutes = String.format(format, (elapsedTime % 3600) / 60);  
		    String hours = String.format(format, elapsedTime / 3600);
		    
			if (hours.length() > 0) {
				time += hours + "H:";
			}
			
			if (minutes.length() > 0) {
				time += minutes + "M:";
			}
			
			time += seconds + "S";
			return time;
		}
		
		return "N/A";
	}
}
